import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:kq_flutter_core_widget/utils/ex/kq_ex.dart';
import 'package:kq_flutter_core_widget/utils/ex/string_ex.dart';
import 'package:kq_flutter_core_widget/utils/log.dart';
import 'package:kq_flutter_core_widget/utils/toast_util.dart';
import 'package:kq_flutter_widgets/widgets/formItem/kq_add_numer_item_view.dart';
import 'package:kq_flutter_widgets/widgets/formItem/kq_checkbox_item_view.dart';
import 'package:kq_flutter_widgets/widgets/formItem/kq_edit_more_view.dart';
import 'package:kq_flutter_widgets/widgets/formItem/kq_edit_upper_lower_item_view.dart';
import 'package:kq_flutter_widgets/widgets/formItem/kq_switcher_item_view.dart';
import 'package:kq_flutter_core_widget/utils/kq_screen_util.dart';

import '../resources/l10n/kq_intl.dart';
import '../widgets/formItem/entity/kq_form_entity.dart';
import '../widgets/formItem/kq_custom_item_view.dart';
import '../widgets/formItem/kq_edit_item_view.dart';
import '../widgets/formItem/kq_empty_item_view.dart';
import '../widgets/formItem/kq_header_item_view.dart';
import '../widgets/formItem/kq_image_box_item_view.dart';
import '../widgets/formItem/kq_only_numer_item_view.dart';
import '../widgets/formItem/kq_radio_item_view.dart';
import '../widgets/formItem/kq_select_item_view.dart';

/// 表单控件辅助工具类
class KqFormUtil {
  /// 渲染多个表单组件，老逻辑，不做处理。
  static List<Widget> renderFormWidgetListOld(List<KqFormEntity> entities) {
    if (entities.isEmpty) {
      return [];
    }
    for (var entity in entities) {
      entity.dividerHorMarginEnable = false;
    }
    return entities.map((e) => renderFormWidget(e)).toList();
  }

  /// 渲染多个表单组件
  /// 会自动根据header或empty分区
  /// [addBottomSpace] 是否自动在底部添加8.r高度，默认true
  static List<Widget> renderFormWidgetList(List<KqFormEntity> entities,
      {bool addBottomSpace = true,
      Widget Function(List<KqFormEntity> group)? customBuilder}) {
    if (entities.isEmpty) {
      return [];
    }

    List<Widget> widgets = [];
    List<KqFormEntity> group = [];

    for (var entity in entities) {
      if (entity.itemType == ItemType.header ||
          entity.itemType == ItemType.empty) {
        // 如果当前有未处理的分组，先渲染分组
        if (group.isNotEmpty) {
          widgets.add(wrapGroup(group));
          group.clear();
        }
        // 单独渲染 header 或 empty
        widgets.add(renderFormWidget(entity, emptyItemViewHeight: 0));
      } else {
        // 将其他类型的控件添加到分组
        group.add(entity);
      }
    }

    // 如果最后还有未处理的分组，渲染它
    if (group.isNotEmpty) {
      Widget result;
      if (customBuilder != null) {
        result = customBuilder(group);
      } else {
        result = wrapGroup(group);
      }
      widgets.add(result);
    }

    if (addBottomSpace) {
      widgets.add(SizedBox(
        height: 8.r,
      ));
    }

    return widgets;
  }

  /// 使用白色圆角包起来，左右添加margin 8.r，顶部添加margin 8.r
  /// topMargin:顶部添加margin 默认: 8.r
  static Widget wrapGroup(List<KqFormEntity> group, {double? topMargin}) {
    // 包装分组，可以根据需求自定义包装逻辑
    return Container(
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(4.r),
      ),
      clipBehavior: Clip.hardEdge,
      margin: EdgeInsets.only(left: 8.r, right: 8.r, top: topMargin ?? 8.r),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: group
            .map((e) => renderFormWidget(e, emptyItemViewHeight: 0))
            .toList(),
      ),
    );
  }

  /// 使用白色圆角包起来，左右添加margin 8.r，顶部添加margin 8.r
  /// topMargin:顶部添加margin 默认: 8.r
  /// bgColor: 背景颜色 默认：白色
  static Widget wrapGroupChildren(List<Widget> children,
      {double? topMargin, Color? bgColor}) {
    // 包装分组，可以根据需求自定义包装逻辑
    return Container(
      decoration: BoxDecoration(
        color: bgColor ?? Colors.white,
        borderRadius: BorderRadius.circular(4.r),
      ),
      clipBehavior: Clip.hardEdge,
      margin: EdgeInsets.only(left: 8.r, right: 8.r, top: topMargin ?? 8.r),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: children,
      ),
    );
  }

  /// 单个使用圆角包起来，
  /// topMargin:顶部添加margin 默认: 8.r
  static Widget wrapSingle({required Widget child, double? topMargin}) {
    // 包装分组，可以根据需求自定义包装逻辑
    return Container(
        clipBehavior: Clip.hardEdge,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(4.r),
        ),
        margin: EdgeInsets.only(left: 8.r, right: 8.r, top: topMargin ?? 8.r),
        child: child);
  }

  /// 渲染单个表单组件
  static Widget renderFormWidget(KqFormEntity entity,
      {double? emptyItemViewHeight}) {
    if (entity.itemType != null) {
      switch (entity.itemType!) {
        case ItemType.edit:
          return KqEditItemView(entity: entity);
        case ItemType.select:
          return KqSelectItemView(entity: entity);
        case ItemType.header:
          return KqHeaderItemView(entity: entity);
        case ItemType.custom:
          return KqCustomItemView(entity: entity);
        case ItemType.addNumber:
          return KqAddNumberItemView(entity: entity);
        case ItemType.onlyNumber:
          return KqOnlyNumberItemView(entity: entity);
        case ItemType.radio:
          return KqRadioItemView(entity: entity);
        case ItemType.imageBox:
          return KqImageBoxItemView(entity: entity);
        case ItemType.empty:
          return KqEmptyItemView(
            height: emptyItemViewHeight,
          );
        case ItemType.switcher:
          return KqSwitcherItemView(entity: entity);
        case ItemType.editBottom:
          return KqEditMoreView(entity: entity);
        case ItemType.checkbox:
          return KqCheckBoxItemView(entity: entity);
        case ItemType.editUpperLower:
          return KqEditUpperLowerItemView(entity: entity);
      }
    }
    return const KqEmptyItemView();
  }

  /// 根据ItemId 查找KqFormEntity
  static KqFormEntity? findEntityByItemId(
      List<KqFormEntity> data, String itemId) {
    for (var value in data) {
      if (value.itemId == itemId) {
        return value;
      }
    }
    return null;
  }

  /// 根据contentKey或contentKeyForShow 查找KqFormEntity
  static KqFormEntity? findEntityByContentKeyOrContentKeyForShow(
      List<KqFormEntity> list,
      {String? contentKey,
      String? contentKeyForShow}) {
    KqFormEntity? entity;
    for (int i = 0; i < list.length; i++) {
      KqFormEntity item = list[i];
      if (contentKey != null) {
        if (contentKeyForShow != null) {
          if (item.contentKey == contentKey &&
              item.contentKeyForShow == contentKeyForShow) {
            entity = item;
            break;
          }
        } else {
          if (item.contentKey == contentKey) {
            entity = item;
            break;
          }
        }
      } else {
        if (contentKeyForShow != null) {
          if (item.contentKeyForShow == contentKeyForShow) {
            entity = item;
            break;
          }
        }
      }
    }
    return entity;
  }

  /// 查找List<KqFormEntity>中所有的itemIds对应的实体
  static List<KqFormEntity> findAllEntityByItemIds(
      List<KqFormEntity> data, List<String> itemIds) {
    List<KqFormEntity> list = [];
    for (var value in data) {
      for (var itemId in itemIds) {
        if (value.itemId == itemId) {
          list.add(value);
        }
      }
    }
    return list;
  }

  /// 根据标题 查找KqFormEntity
  static KqFormEntity? findEntityByTitle(
      List<KqFormEntity> data, String title) {
    for (var value in data) {
      if (value.title == title) {
        return value;
      }
    }
    return null;
  }

  /// 获取第一个显示边框的表单控件
  static findEntityByFocusBorder(List<KqFormEntity> list) {
    for (var value in list) {
      if (value.showFocusBorder) {
        return value;
      }
    }
    return null;
  }

  /// 快捷设置实体类数组中itemId对应实体类的值
  static setValueForEntityByItemId({
    required List<KqFormEntity> list,
    required String itemId,
    String? valueForShow,
    String? valueForSubmit,
    List<String?>? valuesForShow,
    List<String?>? valuesForSubmit,
  }) {
    var item = findEntityByItemId(list, itemId);
    if (item != null) {
      item.valueForSubmit = valueForSubmit;
      item.valueForShow = valueForShow;
      item.valuesForSubmit = valuesForSubmit;
      item.valuesForShow = valuesForShow;
      item.updateWidget();
    }
  }

  /// 快捷设置实体类数组中itemId对应实体类的可见性
  static setVisibleForEntityByItemId({
    required List<KqFormEntity> list,
    required String itemId,
    required bool visible,
  }) {
    var item = findEntityByItemId(list, itemId);
    if (item != null) {
      item.visible = visible;
      item.updateWidget();
    }
  }

  /// 快捷设置实体类数组中itemId对应实体类的是否可编辑
  static setEditableByItemId({
    required List<KqFormEntity> list,
    required String itemId,
    bool? editable,
    bool? editableMask,
  }) {
    var item = findEntityByItemId(list, itemId);
    if (item != null) {
      if (editable != null) {
        item.editable = editable;
      }
      if (editableMask != null) {
        item.editableMask = editableMask;
      }
      item.updateWidget();
    }
  }

  /// 找到数组里[itemId]对应的Entity，并清空表单的数据
  static clearFormValueByItemId(List<KqFormEntity> list, String itemId) {
    var entity2 = KqFormUtil.findEntityByItemId(list, itemId);
    if (entity2 != null) {
      entity2.valueForShow = null;
      entity2.valueForSubmit = null;
      entity2.valuesForShow = null;
      entity2.valuesForSubmit = null;
      entity2.qty = entity2.minQty;
      entity2.imageUrls = [];
      entity2.updateWidget();
    }
  }

  /// 快捷清空实体类数组中所有实体类的值，包括valueForShow，valueForSubmit
  static clearAllFormValue({required List<KqFormEntity> list}) {
    if (list.isNotEmpty) {
      for (var item in list) {
        item.valueForSubmit = null;
        item.valueForShow = null;
        item.valuesForSubmit = null;
        item.valuesForShow = null;
        item.qty = item.minQty;
        item.imageUrls = [];
        item.updateWidget();
      }
    }
  }

  /// 快捷清空实体类数组中itemId对应实体类的值，包括valueForShow，valueForSubmit
  static clearFormValueByItemIds(
      {required List<KqFormEntity> list, required List<String> itemIds}) {
    var items = findAllEntityByItemIds(list, itemIds);
    if (items.isNotEmpty) {
      for (var item in items) {
        item.valueForSubmit = null;
        item.valueForShow = null;
        item.valuesForSubmit = null;
        item.valuesForShow = null;
        item.qty = item.minQty;
        item.imageUrls = [];
        item.updateWidget();
      }
    }
  }

  /// 检查必填项是否填写，未填写自动弹出提示
  ///
  /// 用法：
  /// if(checkMustInputForm(data)) {
  ///    return;
  /// }
  /// 注意：
  /// invalidValueHint 目前仅用于[ItemType.addNumber]的选择数据校验，如果未选择则提示这个。
  /// scrollController 如果必填的数据未填写则滚动到该条位置。
  /// [ignoreInvisibleForm] 未显示的表单直接跳过，不判断是否必填
  ///
  static bool checkMustInputForm(List<KqFormEntity> data,
      {bool checkQty = false,
      bool Function(num qty)? isQtyValid,
      String? invalidValueHint,
      String? invalidQtyHint,
      bool ignoreInvisibleForm = false,
      ScrollController? scrollController}) {
    for (var entity in data) {
      if (ignoreInvisibleForm && !entity.visible) {
        continue;
      }
      if (entity.itemType != null) {
        switch (entity.itemType!) {
          case ItemType.edit:
          case ItemType.editBottom:
            if (entity.mustInput &&
                entity.contentKey != null &&
                (entity.valueForShow == null || entity.valueForShow!.isEmpty) &&
                (entity.valueForSubmit == null ||
                    entity.valueForSubmit!.isEmpty)) {
              KqToast.showNormal(
                  KqIntl.currentResource.pleaseEnter + entity.title);
              if (scrollController != null) {
                entity.widgetState.location(scrollController);
              }
              return true;
            }
            break;
          case ItemType.select:
            if (entity.mustInput &&
                entity.contentKey != null &&
                (entity.valueForSubmit == null ||
                    entity.valueForSubmit!.isEmpty)) {
              KqToast.showNormal(
                  KqIntl.currentResource.pleaseChoose + entity.title);
              if (scrollController != null) {
                entity.widgetState.location(scrollController);
              }
              return true;
            }
            break;
          case ItemType.radio:
            if (entity.mustInput &&
                entity.contentKey != null &&
                (entity.valueForSubmit == null ||
                    entity.valueForSubmit!.isEmpty)) {
              KqToast.showNormal(
                  KqIntl.currentResource.pleaseChoose + entity.title);
              if (scrollController != null) {
                entity.widgetState.location(scrollController);
              }
              return true;
            }
            break;
          case ItemType.header:
            break;
          case ItemType.custom:
            break;
          case ItemType.imageBox:
            if (entity.mustInput &&
                entity.contentKey != null &&
                (entity.imageUrls == null || entity.imageUrls!.isEmpty)) {
              KqToast.showNormal(
                  KqIntl.currentResource.pleaseChoose + entity.title);
              if (scrollController != null) {
                entity.widgetState.location(scrollController);
              }
              return true;
            }
            break;
          case ItemType.addNumber:
            if (entity.mustInput) {
              if (entity.extraData.isEmpty) {
                KqToast.showNormal(
                    KqIntl.currentResource.pleaseAdd + entity.title);
                return true;
              }
              List<KqFormQtyEntity> list = entity.extraData;
              for (var value in list) {
                if (value.valueForSubmit.isNullOrEmpty &&
                    invalidValueHint != null) {
                  KqToast.showNormal(invalidValueHint);
                  if (scrollController != null) {
                    value.widgetState.location(scrollController);
                  }
                  return true;
                }
              }
            }
            break;
          case ItemType.onlyNumber:
            if (entity.mustInput &&
                checkQty &&
                (entity.contentKeyForQty != null ||
                    entity.contentKey != null) &&
                isQtyValid != null) {
              bool valid = isQtyValid(entity.qty);
              if (!valid) {
                if (invalidQtyHint != null) {
                  KqToast.showNormal(invalidQtyHint);
                }
                return true;
              }
            }
            break;
          case ItemType.empty:
            break;
          case ItemType.switcher:
            break;
          case ItemType.checkbox:
            if (entity.mustInput &&
                entity.contentKey != null &&
                (entity.checkBoxData != null &&
                    entity.checkBoxData!.isNotEmpty)) {
              bool checked = false;
              for (var value in entity.checkBoxData!) {
                checked |= value.checked;
              }
              if (!checked) {
                KqToast.showNormal(
                    KqIntl.currentResource.pleaseChoose + entity.title);
                if (scrollController != null) {
                  entity.widgetState.location(scrollController);
                }
                return true;
              }
            }
            break;
          case ItemType.editUpperLower:
            if (entity.mustInput && entity.contentKey != null) {
              if (entity.valuesForSubmit.isNullOrEmpty) {
                KqToast.showNormal(
                    KqIntl.currentResource.pleaseEnter + entity.title);
                if (scrollController != null) {
                  entity.widgetState.location(scrollController);
                }
                return true;
              }
              for (String? value in entity.valuesForSubmit!) {
                if (value.isNullOrEmpty) {
                  KqToast.showNormal(
                      KqIntl.currentResource.pleaseEnter + entity.title);
                  if (scrollController != null) {
                    entity.widgetState.location(scrollController);
                  }
                  return true;
                }
              }
              try {
                if (double.parse(entity.valuesForSubmit![0]!) >
                    double.parse(entity.valuesForSubmit![1]!)) {
                  KqToast.showNormal(
                      entity.title + KqIntl.currentResource.upperLowerTips);
                  if (scrollController != null) {
                    entity.widgetState.location(scrollController);
                  }
                  return true;
                }
              } catch (e) {
                Log.e(e);
                KqToast.showNormal(
                    entity.title + KqIntl.currentResource.upperLowerTips);
                if (scrollController != null) {
                  entity.widgetState.location(scrollController);
                }
                return true;
              }
            }
            break;
        }
      }
    }
    return false;
  }

  /// 生成提交给后端的数据
  static Map<String, dynamic> getFormSubmitJson(List<KqFormEntity> data) {
    Map<String, dynamic> params = {};
    for (var entity in data) {
      if (entity.itemType != null) {
        switch (entity.itemType!) {
          case ItemType.edit:
          case ItemType.editBottom:
            if (entity.contentKey != null) {
              params[entity.contentKey!] =
                  entity.valueForSubmit ?? entity.valueForShow;
            }
            break;
          case ItemType.select:
            if (entity.contentKey != null) {
              params[entity.contentKey!] = entity.valueForSubmit;
            }
            if (entity.contentKeyForShow != null) {
              params[entity.contentKeyForShow!] = entity.valueForShow;
            }
            break;
          case ItemType.radio:
            if (entity.contentKey != null) {
              params[entity.contentKey!] = entity.valueForSubmit;
            }
            if (entity.contentKeyForShow != null) {
              params[entity.contentKeyForShow!] = entity.valueForShow;
            }
            break;
          case ItemType.header:
            break;
          case ItemType.custom:
            if (entity.contentKey != null) {
              params[entity.contentKey!] = entity.valueForSubmit;
            }
            break;
          case ItemType.imageBox:
            if (entity.contentKey != null) {
              params[entity.contentKey!] = entity.valueForSubmit;
            }
            break;
          case ItemType.addNumber:
            // if (entity.contentKey != null) {
            //   params[entity.contentKey!] = entity.valueForSubmit;
            // }
            // if (entity.contentKeyForShow != null) {
            //   params[entity.contentKeyForShow!] = entity.valueForShow;
            // }
            // if (entity.contentKeyForQty != null) {
            //   params[entity.contentKeyForQty!] = entity.qty;
            // }
            break;
          case ItemType.onlyNumber:
            if (entity.contentKey != null) {
              params[entity.contentKey!] = entity.qty;
            }
            if (entity.contentKeyForQty != null) {
              params[entity.contentKeyForQty!] = entity.qty;
            }
            break;
          case ItemType.empty:
            break;
          case ItemType.switcher:
            if (entity.contentKey != null) {
              params[entity.contentKey!] = entity.checked ? 1 : 0;
            }
            break;
          case ItemType.checkbox:
            if (entity.contentKey != null) {
              params[entity.contentKey!] = entity.valueForSubmit;
            }
            if (entity.contentKeyForShow != null) {
              params[entity.contentKeyForShow!] = entity.valueForShow;
            }
            break;
          case ItemType.editUpperLower:
            if (entity.contentKeyForChild.isNotNullOrEmpty) {
              for (int i = 0; i < entity.contentKeyForChild!.length; i++) {
                params[entity.contentKeyForChild![i]] =
                    entity.valuesForSubmit?[i];
              }
            }
            break;
        }
        // 提交单位
        if (entity.contentKeyForUnit != null) {
          params[entity.contentKeyForUnit!] = entity.unit;
        }
      }
    }
    return params;
  }

  /// 设置某个表单控件显示边框，其他控件隐藏边框
  static showFocusBorder(
      List<KqFormEntity> list, KqFormEntity entity, String? placeHolder) {
    for (var element in list) {
      element.showFocusBorder = element == entity;
      if (placeHolder != null) {
        if (element.showFocusBorder) {
          element.valueForShow = placeHolder;
        } else {
          element.valueForShow = element.valueForSubmit;
        }
      }
    }
  }

  /// 从ImageUrl实体类中获取用于提交给[OssNativeUtil.uploadPics]的参数
  static List<Map<String, dynamic>> generateImageBoxOssParams(
      KqFormEntity entity) {
    var imgUrls = entity.imageUrls ?? [];
    List<Map<String, dynamic>> list = [];
    for (var imgUrl in imgUrls) {
      Map<String, dynamic> map = {};
      map['ossKey'] = imgUrl.valueForSubmit;
      map['filePath'] = imgUrl.url;
      map['uploadOk'] = imgUrl.uploadOk;
      list.add(map);
    }
    return list;
  }

  /// 通过[OssNativeUtil.uploadPics]返回结果更新图片上传结果
  static void updateImageBoxUploadStatus(
      KqFormEntity entity, List<Map<String, dynamic>>? uploadPics) {
    if (uploadPics == null || uploadPics.isEmpty) {
      return;
    }

    var imageUrls = entity.imageUrls;
    if (imageUrls == null || imageUrls.isEmpty) {
      return;
    }

    for (var img in imageUrls) {
      if (img.uploadOk) {
        continue;
      }

      for (var uploadPic in uploadPics) {
        if (img.valueForSubmit == uploadPic['ossKey']) {
          img.uploadOk = uploadPic['uploadOk'] ?? false;
          break;
        }
      }
    }
  }

  /// 检查oss上传是否没有全部成功，不成功则返回true
  /// 默认会自动提示[图片上传失败，请重试]，如果不想自动提示，则设置[showToast]=false
  static bool checkOssUploadFailed(List<Map<String, dynamic>>? result,
      {bool showToast = true}) {
    if (result == null) {
      return false;
    }
    for (var value in result) {
      var uploadOk = value['uploadOk'];
      if (!uploadOk) {
        KqToast.showNormal(KqIntl.currentResource.imgUploadFail);
        return true;
      }
    }
    return false;
  }
}
